/************************************************************************
*************************************************************************
*************************************************************************

acf2.do

Code to run the Ackerberg-Caves-Frazer estimator of a value-added production function.
This version uses more of a two-step approach to netting out productivity (similar
to GNR).

04 11 2015: Created from acf.do


Arguments:
y k l m donl

y,k,l,m			- 	log output,capital,labor,flexible inputs
donl 			- 	Allow nonlinear process for productivity?



*************************************************************************
*************************************************************************
************************************************************************/


/*****************************************************************
Product [Utility program]
*****************************************************************/

//Recursive program to get the pairwise products of a set of terms
cap program drop product
program product
	syntax varlist
	
	gettoken firstvar resvars : varlist	
		
	//Take the product
	foreach var of varlist `varlist' {
		gen `firstvar'X`var' = `firstvar'*`var'
	}
	
	//If we're not on the last word, keep going
	if !mi(word("`resvars'",1)) {
		//Continue recursion
		product `resvars'
	}
end


/*****************************************************************
acf_prog [Function Evaluator for GMM]
*****************************************************************/


cap program drop acf_prog
program acf_prog


	syntax varlist [if] , at(name) y(varname) stage1pred(varname) k(varname) lab(varname) [donl]
	
	quietly {
		tempvar omega lomega xb
		matrix score double `xb' = `at' `if', eq(#1)

		//gen `omega' 	= `stage1pred' - `xb' `if'
		gen `omega' 	= `y' - `xb' `if'
		gen `lomega'	= l.`stage1pred' - l.`xb' `if'
		

		
		//Assume markov process is a third-order polynomial
		if !mi("`donl'") {
			foreach deg of numlist 1/3 {
				tempvar poly`deg'
				gen `poly`deg'' = `lomega'^`deg'
			}

			
			reg `omega' `poly1' `poly2' `poly3' `if' 
		}
		
		//Assume markov process is autoregressive
		else {
			
			reg `omega' `lomega' `if'
		}
		
		tempvar tmp
		predict `tmp' , resid
		replace `varlist' = `tmp' `if'
						
	}
end


cap program drop acf2
program acf2

	args y k l m donl
	
	
	/********** Part 1: Strip out the unanticipated shock **********/
	
	//If the second-order terms don't exist, create them
	cap confirm var `k'X`k'
	if _rc != 0 {
		di "Product not found!"
		order `k' `l' `m', last
		product `k' `l' `m'
	}
	
	
	
	
	//Strip out the shock, which is uncorrelated with the factors of production
	quietly {
		tempvar stage1pred
		reg `y' `k'-`m'X`m'
		predict `stage1pred'
	}
	
	/********** Part 2: Estimate the parameters **********/
	
	
	#delimit;
	gmm acf_prog, 	nequations(1) stage1pred(`stage1pred') `donl' y(y) k(k) lab(l)
					parameters( y:`k' y:`l' y:`k'X`k' y:`k'X`l' y:`l'X`l' )
					instruments(  `k' `l' `k'X`k' `l'X`l' `k'X`l'
									l.(`k' `l' `k'X`k' `l'X`l' `k'X`l' `stage1pred') )
					conv_maxiter(100) ;
	#delimit cr

end
